how to get

MMB PlugIns

work for you

Pocket-sized operator's manual

with pictures and schemes included

by bokzy, 2003.

Ok, so you tried MMB, bought it the very next day, spent weeks learning MMB scripting language and just as you thought you've got all twines in your hands - Murphy in the form of your first neighbour comes, storming you with words:

"John, can you borrow me some nails, hammer and a copy of tweak plugin with some samples for it ?"

Nails and hammer are somewhere in garage, but what in heck is tweak plugin, what he needs that for ?

You choose to improvise. Got some rusty nails, hammer's got a broken handle but it'll do it - and tweak ? He probably needs AC/DC plug, so you pick one from your collection and everything's there.

Except the smile on your neighbour's face.

It must be 'cause nails are little rusty.

Is it ?

Hm, not exactly.

Yes he took hammer and the nails, but why did he throw away that AC/DC you gave him ? It's broken ?

Very next day you're going for a visit. Entering neighbour's house, starting some ordinary chit-chat with a beer in your hand... having one eye on computer screen... yep, you see he's working on something in MMB. Yep, you see he's even using scripting editor (so that's why he spent last 10 nights awake).

Yep... Script commands flying around - Show, Hide, even MoveObject is there... VolumeUp, VolumeDown, Plugin.... errr... what was that ?

Plugin...Set ?

What for ? You were so successful in ignoring that command !

So far.

Some other film starts to roll in your head. He didn't want AC/DC plug ! It was a trap, to see how far you've gone in using MMB !

Finishing your second beer you hurry home, slam the doors, start computer... got some serious talks with MMB again !

Time to spend few extra nights not in bed with your deareast, but with MMB and that plugin thing !

PlugIns everywhere

Let's skip that part "it all began 200 years ago..."

...'cause it didn't ;-)

Most of today's computer users got a chance to experience PlugIns, sometimes without even knowing about it.

For a long period of time, extra functionality was handled through various sub-routines built into the main program. So you changed entire program to experience difference. Someone, somewhere thought of a new approach - why not make external units that could be added / changed like bricks. In fact, why not allow people all over the world to make these bricks ?

So they did it - once agreement was made, standards built, documentation & tutorials became available worldwide - didn't have to wait too long to get some attention !

Does it mean we had to wait for standardization to get PlugIns ?

Yep ! Standardization on more levels.

Today you can find PlugIns everywhere - in paint tools, video editing applications, multimedia players, e-mail clients...

But how do they work ? What's the game ?

Space station - collection of plug-ins

You surely did see at least one space station. They fly not so high above our heads, here and there fall and by shape are far from things we use to see in SF movies.

Now imagine MMB being a central structure of the space station:



Ok, yeah, this doesnt' look much like a space station without solar cells... More like a composition of fire cannons attached one to another :-)

Anyway. Here we have a MMB Space Station, representing MMB as application itself. You can live in this station. But after some time you'll feel a need to get some extra furniture. And that furniture will require some space. After all, you want a few more acres of space too, so you can kick off your shoes and enjoy in the fresh air.

Thanks to station gateways - you can ! It's all about going to a resource shop and taking whatever you need. Some are free, some require a small fee ! Cash & carry, easy installation, don't worry !



* Beer PlugIn is under development

Now you have The Station ! More space, more power and it looks a way cooler than your neighbour's !

Rubber gateways

Let's face it - for the very first plugin/module installations to your MMB Space Station you'll call a local plumber.

Don't want to ? Then welcome to:

Small Do-It-Yourself MMB Plumber Operator's Manual

While MMB takes care of all it's rubber gateways, your part of the installation job ain't very difficult if you track pictures of this manual. Yeah. It's such an enormous difference between difficulty of plugin installation and usage !

Ingredients:

  • 1 MMB
  • 1 PlugIn
  • Unlimited amount of coffee

You started MMB, no problem, but how do you recognize MMB PlugIn ?

It's a file like any other, but with weird extension - DLL . Here are some examples of MMB PlugIn file names:

tweak.dll

misc.dll

posxy.dll

EditBoxPlugIn.dll

Names usually represent basic function of PlugIns. It's hard to find some cryptic one like

3ksvow843beer.dll

Got your cup of coffee ?

Good !

Where will you find MMB PlugIns ?

There are various places to start with, but to keep this answer short, recommendations of Operator's Manual are:

  • visit www.mmbforums.com where you'll find MMB Community Links index, having good collection of links to sites with PlugIn resources
  • visit some of MMB-related sites (called Resource Sites 'cause they hold various MMB community resources):
  • MicroTech's MMB Resource Site:
    http://www.advanced-microtechnologies.com
  • Squash Productions plugins:
    http://www.squashplugins.cjb.net/
  • Yomo's site (home of Plugy plugin!):
    http://www.mmdev.net/yomo/home.htm
  • RastaWorld Productions:
    http://www.rastaworld.com/
  • Bokzy's site
    http://www.bokzy.com/

Links might change in time, so if you get 404 try google search.

Back to our MMB plumber business !

You made a nice collection of those DLL's and now you're back to this manual. What now ?

Take a look at MMB window. Let's see what can be found here...




Naaaahhh....

Keep searching.

Trying again, and.... BINGO !


Well, more something like "PlugIn" than "BinGo", at the end of object menu list or Object ToolBar..

Click on "PlugIn" item and your mouse pointer will turn into a drawing cross, signalizing you'll have to draw a rectangle that will later be a PlugIn window (if it's one of those visible PlugIns).

You're able to adjust position and size of PlugIn's rectangle later, so don't pay much attention to it now.


Hey ! This is flat and doesn't look like 3D module for my Space Station !

Well, yeah... you know, it's like one of those Santa Clause things... They tell you the truth later....

At least you have a PlugIn rectangle ! Double click on it.

New dialogbox pops up, it's pretty simple:



Label, Hide & Lock Position are features available for all MMB objects. You should only remember PlugIn Label.

Below this standard features, there's an editbox, titled "Plug In:" .

On the right side of editbox there's "..." button, signalizing you can browse for PlugIn file on your data drives. Push it !

Well-known "Open File" dialogbox is displayed, allowing you to select DLL file - MMB PlugIn.

If you made a collection of MMB PlugIns by downloading 'em from resource / plugin developer sites - you'll go to that location and select a file.

Don't have anything in collection ? Go to MMB's installation folder and then to \Plugins sub-folder. There you'll find small PlugIn provided by Mediachance together with MMB, called TenBlobs.dll

Once you select file and click "Open" button - MMB will ask what it should do with it:

"Do you want to move PlugIn to embedded files ?"

Click -> Yes

In this case, PlugIn will be embedded (attached) to your project. Star Trek fans would use expression "assimilated" ;-)

Once PlugIn is embedded, you won't have to worry about it's location after finishing your application. MMB will pack everything together. Just for notice - it has it's drawback, but more about it later !

After you assimilated MMB PlugIn, dialogbox will look like this:


Path to DLL file contains prefix <Embedded>\

This is called "path macro tag", and in this case signalizes that Tweak.dll is embedded into your project. More about path macros available in MMB's help file.

Below path editbox there's a text memo with comment - place where PlugIn developers put some important info: copyright, author name, support page URL & e-mail, etc.

Click on OK button and that's it ! If you carefully listed Plumber's Manual - installation of MMB PlugIn in your project is done !

Save your project, close everything and come back tomorrow.

Good morning. You have 1 PlugIn object

After adding MMB PlugIn to project, maybe you felt like something's missing. Where are all those dialogboxes and controls well-known from other software PlugIns ?

Hm.

Approach to changing MMB PlugIn properties is somewhat different.

If you try using TenBlobs PlugIn, provided with MMB, you'll notice ability to change some parameters using Properties dialogbox.

All other MMB PlugIns use commands to do it.

Why is that so ?

While using MMB script language and trying some demos from MMB community, you probably figured out it can be used for much wider range of applications than autorun menus and install screens.

Starting from that point, MMB PlugIns offer ability to be controlled from your application. Anytime, anywhere - using MMB's script language.

That's a great advantage !

You can load, save & set different parameters, perform property changes in loops and during runtime mode...everything without the need for end-user interaction.

Imagine how annoying would be, to bother users with property dialogboxes popping up every minute, asking for intervention... ;-)

That's right ! Let's admit it - usage of PlugIns and script language is programming. So we have some serious business here.

Behind the curtain

Let's spend a few words for readers who want to know more on MMB PlugIn mechanics subject.

That's right, technical mumbo-jumbo coming, read carefully.

MMB PlugIns are DLLs - Dynamic Link Libraries. Meaning, they are organized collections of commands / functions.
Remember rubber gateways from MMB Space Station ? PlugIn developers use 'em to communicate with MMB.

:-)

So we're talking about some kind of communication channels here. And some are used just for internal purposes, but for sake of this manual let's point out those important to PlugIn users:

  • setting & retrieving of integer variables
  • setting & retrieving of string variables
  • running of specified command

You must get familiar with string & integer variables to use MMB script language. Still didn't ? Close this manual, open Help in MMB and come back when you're done with variable research.

Here's another order of PlugIn<->MMB communication:

  • setting parameters through variables (either integer or string)
  • running of PlugIn command (parameter not always necessary)
  • getting values from PlugIn through variables (not always necessary)

This order points out general & very important PlugIn usage sequence. More about it later.

Types of MMB PlugIns

There are two (2) types of PlugIns:

MMB PlugIn Type 1: 98% of MMB PlugIns. They differ from standard applications by the fact they're DLLs communicating with parent (MMB) application through commands ("channels") and their visual elements are drawed inside the defined PlugIn window of MMB-made application.

Everything else is practically independent from parent (MMB) program - all command processing happens inside the PlugIn. Output of executed command either performs change on PlugIn objects or goes to string / integer variable. And that's entire scope PlugIn covers ! No much interactivity with MMB, eh.

This is very important to understand -Type 1 PlugIns work almost independently in their own windows set by MMB, so they cannot affect other MMB objects - but this lack of interactivity also disables covering of Type 1 PlugIn window with other MMB objects.

It's something you'll notice while using visible PlugIns - those with visual objects like EditBox PlugIn, SlideShow PlugIn, etc.


Another thing to keep in mind when using visible Type 1 PlugIns: they can't be run in multiple instances if one DLL is being used.

Resources can't be shared, so if you, for example, need two editboxes performed by EditBox PlugIn - two EditBoxPlugIn.dll files are required. You should rename them and have:

EditBoxPlugIn1.dll

EditBoxPlugIn2.dll

To get two PlugIns work simultaneously, you'll perform adding of PlugIn objects twice, as explained in Plumber's Operator Manual.



You have two PlugIn objects now. First is labeled "PlugIn1", and second one "PlugIn2". This labels are important while using PlugIn commands, they serve as reference to 'em.

Like when sending mail - you'll need destination address. In this case, you'll need PlugIn's destination - label.

And how do we use PlugIn commands ? That's most important part of this tutorial, coming up soon ! Keep reading ;-)

MMB PlugIn Type 2: this type enables multiple instances of visible PlugIns and covering with MMB objects. But it proved to be unstable, so it's rarely used. MMB comes with Type 2 PlugIn example, called TenBlobs.dll

In front of the curtain

Phew ! That previous chapter was a way too serious.

What have we learned so far ?

  • PlugIns are everywhere
  • They are additions to main products
  • Their purpose is increasing of main product capabilities
  • MMB PlugIns are not easy to install
  • Neighbour's project is still more powerful

No more time to spend on theory ! We must move to practice !

ASAP !

After crawling through installation of MMB PlugIns, one would probably ask:

OK, what's the story now ? They're not like space station modules (and you can live with that), but also not like audio plugins in WinAmp, graphics plugins in Photoshop and they're far away from Premiere video plugins !

Opening of audio plugin properties in WinAmp will display something like this:


...but if you try something like that in MMB PlugIn Properties window...



...in 98% of PlugIns you will get:



NOTHING !

What now ?

- Hm. Seems like we'll have to change MMB PlugIn properties somewhere else.

Where ?

- In MMB Script Window, using MMB Script Language !

Visiting another planet


If your first impression on seeing this window was "What in heck is that ?!?" - you will unfortunately have to leave MMB PlugIn Operator's Manual at this point, take MMB Help or some other MMB General / Scripting Tutorial and start your research on

MMB Script Language

It's a foundation of using MMB PlugIns - without knowing how variables work or where to use them - you would pull half of your hair out by reading this tutorial any further.

And it's not like you must become an expert in this script language to start using PlugIns !

The most important scripting parts are:

working with integer and string variables

structure of MMB script language commands

using functions (if-then statements, for-next loops) & path macro tags (<SrcDir>, <Embedded>, etc.)

The Practice

No longer can this Manual save readers from ugly business !

We're now going right to the center of Ugly PlugIn Beast?

Fasten your seat belts.


LAW & CONSTITUTION OF MMB PLUGINS

There are 3 (three) PlugIn-related commands you use in MMB script language to communicate with PlugIns !

You enter these 3 commands in MMB script window, either at:

Script Icon of MMB Object

or...

MMB Script Object

So we're talking about

FELLOWSHIP OF 3 COMMANDS

PluginSet

MMB script command being used for setting of parameters. Once set, parameters are "memorized" in PlugIn. And PlugIn will use them for running of command (specified using PluginRun script command).

What are these parameters ? MMB string and integer variables, containing some value.

If you use PluginSet twice, previously "memorized" parameters will be substituted with new ones. So it's not some kind of container you'll fill repeatedly, and expect it to hold everything ;-)

PluginRun

MMB script command that is used for running of PlugIn command. To know what commands are available, refer to Documentation / Help file / Tutorial / Readme file that (in most cases) comes with PlugIn.

If you're not able to find any reference, try contacting PlugIn author or visit MMB Forums, searching for help on this subject.

Most of commands either require input parameters through PluginSet or give output you're able to retrieve using PluginGet.

Executed commands:

  1. do not always require input parameters set using PluginSet command
  2. do not always give output retrievable using PluginGet command
  3. sometimes change only PlugIn's status

PluginGet


MMB script command that is used for retrieving of parameters.

PlugIn command executed using PluginRun can return some result (either into string or integer variable). With PluginGet you're able to get this content, so you'll naturally use it after PluginRun.

Fido - PlugIn Dog

Pictures are worth more than thousands of words, so let's now see how good old Fido deals with 3 MMB PlugIn commands !


Although our Fido doesn't look happy about his task, one thing is for sure - PlugIns won't complain and give you strange looks, no matter how many times you repeat 3 command steps, no matter how many bones you throw ;-)

Scripting versions

You must have thought "Yeah, right, no way these commands can work just like that, without anything attached to 'em".

And you're right - like most of MMB script commands, these also use brackets and quotes to enable setting of parameters.

PluginSet

In Theory

In Practice


PluginSet


PluginSet("PlugIn","var$")


Explanation:

  1. PluginSet - command that will set some parameters to be used by PlugIn later, through PluginRun command
  1. "PlugIn" - label (inside quotes) of PlugIn object you refer to. Just as you would write address on letter envelope before sending, this part will tell MMB where to send parameters (in this case to PlugIn object labeled "PlugIn" ; but you can change that label by double-clicking on PlugIn object in MMB.)
  1. "var$" - name of variable (inside quotes) that contains parameter(s) you want PlugIn to use later through PluginRun command. This variable can be either of integer or string type - and to know what type you should use - refer to Documentation of PlugIn, where this important info will be mentioned in description or command example. Every PlugIn command can either
    1. use integer input variable (for e.g. var),
    1. string input variable (for e.g. var$) or
    1. do not use entire PluginSet command at all (if it's only output-related, meaning, doesn't require any input).


PluginRun ain't different in structure. Only noticable change is third part of command, where you do not specify variables, but run actual PlugIn commands:

PluginRun

In Theory

In Practice


PluginRun


PluginRun("PlugIn","UpperCase")


Explanation:

  1. PluginRun - command that will run (now this is fuzzy, check this out:) - PlugIn command !
    Command that runs command ? Yep.
  1. "PlugIn" - label (inside quotes) of PlugIn object you refer to. Just as you would write address on letter envelope before sending, this part will tell MMB where to send parameters (in this case to PlugIn object labeled "PlugIn" ; but you can change that label by double-clicking on PlugIn object in MMB.)
  1. "UpperCase" - actual PlugIn command that will be run upon calling PluginRun. How will you know what commands to use ? Refer to Documentation of PlugIn or some of it's demos - you'll also find descriptions and examples of PlugIn command usage, with all necessary input and/or output variables for PluginSet & PluginGet commands.

To clear this up: here we have two kinds of commands:

    1. script command PluginRun (MMB's script command)\
    2. PlugIn command that is run using PluginRun (and you'll have to read PlugIn documentation to see how these commands are named)

As you would run any program - once MMB executes PluginRun, PlugIn will do it's job. And if obliged will return output integer and/or string variable that you're able to retrieve using PluginGet script command.


Similar to PluginGet, this one also uses variables as command's third part, but this time to receive a value - from PlugIn !

PluginGet

In Theory

In Practice


PluginGet


PluginGet("PlugIn","var$")


Explanation:

  1. PluginGet - command that will retrieve a value from PlugIn after it's command has been run using PluginRun
  1. "PlugIn" - label (inside quotes) of PlugIn object you refer to. Just as you would write address on letter envelope before sending, this part will tell MMB where to send parameters (in this case to PlugIn object labeled "PlugIn" ; but you can change that label by double-clicking on PlugIn object in MMB.)
  1. "var$" - name of variable (inside quotes) that will be filled with contents received from PlugIn after PluginRun command. This variable can be either of integer or string type - and to know what type you should use - refer to Documentation of PlugIn, where this important info will be mentioned in description or command example. Every PlugIn command can either
    1. use integer output variable (for e.g. var),
    2. string output variable (for e.g. var$) or
    3. do not use entire PluginGet command at all (if it's only input-related or doesn't use any variables / parameters at all).

Put it, shake it, get it - v╘ila ! Virtual example 1 !

Now we'll extract important lines from tables above, put 'em one after another and we'll get somethin' like...

PluginSet("PlugIn","var$")

PluginRun("PlugIn","UpperCase")

PluginGet("PlugIn","var$")

Here we are ! First block of PlugIn script lines has been completed !

Didn't hurt much, but what this particular code does ?

It's an example. Of some virtual PlugIn (object is labeled as default one would be - "PlugIn"), in service of script line block above, that

  • takes input string variable (var$) with PluginSet,
  • executes PlugIn command named "UpperCase" with PluginRun,
  • retrieves a value from PlugIn after PluginRun and fills string variable (var$) using PluginRun

This PlugIn command serves as a good example - uses input variable to set some value to PlugIn for processing, runs PlugIn command and retrieves processed content to some variable.

Let's extend this script lines with a few more, MMB-related:

var$ ='Welcome home, Joe'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","UpperCase")

PluginGet("PlugIn","text$")

Message("MMB says:","text$")

Now we already have entire program ! It fills var$ string variable with "Welcome home, Joe" text, assigns that content to PlugIn (with PluginSet), runs PlugIn command UpperCase (with PluginRun), retrieves result into text$ output string variable (with PluginGet) and at the end - displays processed text in MMB's MessageBox !

It's about time to mention what actually UpperCase command from this PlugIn does - it converts input text to upper-case version and brings it back to MMB. Alive and upper-cased :-) So text "Welcome home, Joe" is converted to screaming "WELCOME HOME, JOE" :-)

Virtual Example 2 - Input without Output

We'll take our virtual, non-existing PlugIn once more and see what script code lines will be used if input through variables is required - but there's no output (PlugIn doesn't tell anything after PluginRun).

When do we need this ? Usually when input variable is just a parameter that will be 'consumed' by PlugIn - either to change some color, increase / decrease font size, start some important command in PlugIn (like Connect, EncryptFile, SetMute) or even to send message over the Internet or set parameter for some other PlugIn command (for e.g. setting of source file can be done with command like SetSourceFile, setting of destination file with similar SetDestinationFile, and after using both of 'em you'll use third PlugIn command - CopyAllFiles).

Needs input, but we can't expect output (more precisely, output through integer/string variable). Script commands that will be used to perform this are:

  • PluginSet
  • PluginRun

Having virtual PlugIn, let's now imagine browsing through it's documentation ! Our task is - finding description and example of some command that will show a Message Box. While this PlugIn can display Message Box, let's use it !

Searching through PlugIn's docs takes us to description of something that could serve this purpose:

Virtual PlugIn Documentation

General Commands

Command name: DrinkCoffee

Description: Makes your computer walk to the kitchen, drinks a coffee and returns to you fresh and ready for another portion of heavy work in MMB.


Example:

var$ ='Black,Milk,Sugar'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","DrinkCoffee")


Hmm.... well that could do it, but Message Box still won't be displayed :-)

Continue exploring strange jungle of PlugIn Documentation....

Virtual PlugIn Documentation

General Commands

Command name: ShowMessageBox

Description: Does not walk or drink coffee. This command shows Message Box with OK button. Use input string variable to specify message you want to display in Message Box.


Example:

var$ ='I am not coffee addict, I swear !'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","ShowMessageBox")


Yeah, looks like it !

As you can see from this frames - documentation has it's title (Virtual PlugIn Documentation), subtitle that specifies command range (in this case - General Commands) and listings of commands with their descriptions and examples.

Most of MMB PlugIn docs presume that PlugIn's object in MMB will be called "PlugIn". So you should check it's label and adjust either PlugIn object label or script code lines.


 

 

 

 

 

 

 

After reading description of ShowMessageBox command, you decide to use provided example. By simple copying from PlugIn documentation and pasting into MMB's Script Window, you'll get:

var$ ='I am not coffee addict, I swear !'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","ShowMessageBox")

Let's get familiar with these lines...

First line assigns text to string variable named var$

var$ ='I am not coffee addict, I swear !'

Second line uses PluginSet to assign var$ to PlugIn

PluginSet("PlugIn","var$")

And finally - we'll call PluginRun to tell PlugIn: "Hey,PlugIn , it's all set and now it's time for you to run ShowMessageBox command."

PluginRun("PlugIn","ShowMessageBox")

And the result ? We'll see it on the screen !




Notice: you won't always be able to copy/paste all command examples from documentation and expect 'em to work without adjustments. They can depend on some other commands or scripts, you can have different labels or requests from these commands - examples usually show basic functioning of PlugIn commands and it's on you to get the best from 'em (for e.g. improve the script above in the way your users can enter message in an EditBox and by clicking on the button display it using PlugIn's ShowMessageBox).

Virtual Example 3 - Output without Input

While exploring hundreds of commands through documentation of various PlugIns, you'll bump into this type of PlugIn commands - they don't require any input in the form of string or integer variable - but they are run using PluginRun and you can pick result of their work, using PluginGet script command.

What are commands of this type for ?

Mostly for retrieving:

  • information from PlugIn
  • information from the system

In most cases you'll use it to pick information, like system date & time, read INI files, available RAM memory, read Windows Registry, find out about mouse position or pressed keys, get media file info, etc, etc....

Let's pick a date !

Back to PlugIn docs !

Virtual PlugIn Documentation

Info Commands

Command name: GetSystemDate

Description: This command retrieves current system date and puts result into output string variable.

Example:

PluginRun("PlugIn","GetSystemDate")

PluginGet("PlugIn","date$")


We'll naturally copy/paste this example into MMB's Script Window.

PluginRun("PlugIn","GetSystemDate")

PluginGet("PlugIn","date$")

Notice a difference - there's no input variable anymore - we'll immediately use PluginRun to tell PlugIn "Hi again, PlugIn , sorry for bothering you, but could you please pick up current date from this system with that GetSystemDate you got there ?".

With PluginGet comes another instruction, saying to PlugIn:

"Doh, almost forgot - put the date into date$ so I can use it in my beautiful MMB project !".

You'll make adjustments in this example, of course, so retrieved date will be, if nothing else, displayed in MMB's MessageBox:

PluginRun("PlugIn","GetSystemDate")

PluginGet("PlugIn","date$")

Message("Current system date is:","date$")

Let's see the result:




Similar example to this one can use command like GetSystemYear to retrieve current year into integer variable:

PluginRun("PlugIn","GetSystemYear")

PluginGet("PlugIn","year")

Message("Current year is:","year")

Here, the result of PluginRun , that executed PlugIn's GetSystemYear command, went into integer output variable year

Once retrieved into integer variable, you can perform various math operations available in MMB's script language.

Virtual Example 4 - No Input - No Output ?

Yep, you'll find these too ! Strange kind of commands.... they ask for nothing....they give nothing. What are they for then ?

Well - for things that simply need no assistance through parameters and don't feel need to give you any result !

And there are plenty of them - Play, Stop, Show, Clear...

Another visit to PlugIn documentation, this time we'll look for a command that will show PlugIn window (let's presume this PlugIn is of visual type, having visualizations for which would be a shame not to have visibility in MMB application).

Virtual PlugIn Documentation

General Commands

Command name: Show

Description: This command shows PlugIn window and it's contents.

Example:

PluginRun(" PlugIn","Show")

Again we get this code example into MMB Script Window:

PluginRun("PlugIn","Show")

Now this one is easy ! No messing around with variables, you just call PluginRun and it executes PlugIn command Show !

With Show command in PlugIn also usually comes Hide command that will do the opposite - it will hide PlugIn window.

Also no variables needed, you just run that one sweet line:

PluginRun("PlugIn","Hide")

Combining Examples 1 & 2

We're moving to advanced example, that combines PlugIn's command types 1 & 2 - meaning, we'll

  • use UpperCase command with all around it to convert text into upper-case version, and use the result to
  • set input string variable for ShowMessageBox command

var$ ='My computer is coffee addict !'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","UpperCase")

PluginGet("PlugIn","text$")

PluginSet("PlugIn","text$")

PluginRun("PlugIn","ShowMessageBox")

Check that out ! Entire sequence of commands that starts with

var$ ='My computer is coffee addict !'

...and ends with...


There's no limitation in number of sequences you can run in this way - and it's very neat to run 'em in loops.

PlugIns & Variables

Let's spend some time with examples that will prepare you for various aromas of input & output variables used with PlugIns.

Example with basic string input variable

In action we'll see already used virtual PlugIn command for displaying message box, called ShowMessageBox.

With input string variable var$ you set text that will be displayed in PlugIn's message box:

var$ ='Live long and prosper !'

Using PluginSet command, content of var$ will be assigned to PlugIn:

PluginSet("PlugIn","var$")

And by calling PluginRun, message box will be displayed:

PluginRun("PlugIn","ShowMessageBox")

Result is visible on screen:



Examples with advanced string input variable

With normal strings, you'll set text either in word or sentence form. What exactly would be advanced string, then ?

It's a kind of input string that is required by PlugIn, to set it's property / setting.

In fact, there are two versions of PlugIn property/setting input strings...

  • upper-cased property strings
  • comma-delimited setting strings

Here's what makes difference between these:

Upper-cased property strings

As you guess, it has something to do with upper-case written words. What will you use it for ?

To set PlugIn's properties like window border and mouse click events. They require (usually single) word inputs as arguments that will set PlugIn's property after calling specific command. And upper-case words are convention used within MMB PlugIns.

This example will set single-line border on virtual PlugIn window, using word SINGLE, as input string parameter, and SetBorder PlugIn command to assign input parameter.

var$ ='SINGLE'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","SetBorder")

Authors of PlugIns mention available string input parameters in PlugIn's documentation, so you don't have to take a guess ;-)

Comma-delimited setting strings

Comma-delimited string = describes advanced string that uses comma , as border between two words.

Setting string = kind of string that will change PlugIn setting

 

Two most usual (and important) cases where you'll use comma-delimited setting strings are:

  • Setting of background / foreground color values
  • Setting of event handlers

About event handlers and colors read more below Manual's example section. This is quite important subject for comfortable life with MMB PlugIns, so it's recommended to jump over and read about these subjects right now.

Example of comma-delimited string in service of background color setting using virtual PlugIn's command SetBackColor coming up:

var$ ='10,201,20'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","SetBackColor")

After running this example, background color of virtual PlugIn window would look like this:




While we're here, let's see example of comma-delimited string in service of event handler setting using virtual PlugIn's command SetHandler:

var$ ='CTRL,SHIFT,ALT,U'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","SetHandler")

The result of setting event handler to this key combination would be demonstrated after event occurs - CTRL, SHIFT, ALT and U keys would be triggered and passed to your application.

Examples with integer input variable

Another commonly used input variable type is integer - there are numerous PlugIn commands what will use exactly this type to set volume, font size, media position, number of seconds, etc, etc...

To keep it simple, this example will set PlugIn's font size.

With input integer variable var you set TrueType font size:

var =18

Using PluginSet command, value of var variable will be assigned to PlugIn:

PluginSet("PlugIn","var")

And by calling PluginRun, font size will be applied using virtual PlugIn's command SetFontSize:

PluginRun("PlugIn","SetFontSize")

Here's how code looks like if we put it together:

var =18

PluginSet("PlugIn","var")

PluginRun("PlugIn","SetFontSize")

And the result is PlugIn's font size set to 18:

Text sample


Another standard integer input is setting of PlugIn's sound volume. Available values in this case are usually in range 0-100 and PlugIns will ignore any lower or greater values. For this example, SetVolume command of virtual PlugIn is being used to assign value from var integer variable and adjust PlugIn's sound volume.

var =18

PluginSet("PlugIn","var")

PluginRun("PlugIn","SetVolume")

(sound speakers and media players are not provided with this manual, so try to imagine the result of this script code)

Example with basic string output variable

Almost all PlugIn commands that return strings will give you result using basic string output type. The result will be ordinary word, couple of words, sentence, etc.

You already experienced string outputs in UpperCase and GetSystemDate command examples. Right after using PluginRun you'll call PluginGet to retrieve string - result of PlugIn's work.

Using virtual PlugIn's command GetComputerName:

PluginRun("PlugIn","GetComputerName")

...script command PluginGet will retrieve basic string output into var$ string variable:

PluginGet("PlugIn","var$")

Once retrieved, you can do whatever you want with it. This example will show computer's name using MMB's message box:

Message("Computer name is:","var$")

Code put together:

PluginRun("PlugIn","GetComputerName")

PluginGet("PlugIn","var$")

Message("Computer name is:","var$")

Here's result displayed in MMB's message box:


Examples with advanced string output variable

This kind of string output is being used in two cases:

  • PlugIn's event messages
  • character-delimited strings

Let's get to:

PlugIn's event messages

Some paragraphs above this manual redirected you to sections that explain event handling and color properties. You did read 'em before coming back, didn't you ?

Good ! Then you know about PlugIns returning string or integer event messages, informing you what exact event has occured.

Once event happens, script object set to catch key combination, sent by PlugIn, will use PluginGet to retrieve output variable. This paragraph is dedicated to string output variables, so in this case string output will be retrieved:

PluginGet("PlugIn","var$")

What will var$ be filled with ? PlugIn returns event message, so if it just finished drinking his beer, returned string might be

I just finished my third beer. Buurp.

Once this event message is sent to var$ output string variable, you'll either display it using some text object or use if-statements to decide what to do in the case of a third beer:

If (var$ ='I just finished my third beer. Buurp.') Then

Exit()

Return()

End

It's important to follow exact letter cases and spaces - MMB is case-sensitive, so your if-statement string must exactly match PlugIn's event message. Example above won't work if you use:

if (var$ ='i just finished my third beer.buurp.') then

...because upper-case letters and one space are missing.

Character-delimited strings

Don't worry. This type is rarely used.

PlugIn will return output string variable that consists of multiple strings, delimited with character (set by PlugIn's author).

With this string type (something like array) PlugIn can return multiple items without using PluginRun over and over again, but to separate individual strings you'll need some extra coding - so there are just a few cases when PlugIn will return this string output type.

Once PluginRun is executed, you will use PluginGet to retrieve output string variable:

PluginGet("PlugIn","var$")

What will var$ be filled with in this case ? Character-delimited string that will look like:

dog|cat|horse|snake|rabbit|mouse

This example uses | character as delimiter (separator). Of course, it can be some other character:

dog*cat*horse*snake*rabbit*mouse

...and to know what character is being used in PlugIn (in some cases you can even set your own delimiter character), check out PlugIn's documentation.

Examples with integer output variable

PlugIn commands will frequently give you result using integer (number) output type. From count & calculation results to position status and sizes in bytes - all numerical outputs go into integer output variables.

So far you experienced integer output in GetSystemYear command example. Right after using PluginRun you'll call PluginGet to retrieve integer - result of PlugIn's work.

Ordinary integer output example

Using virtual PlugIn's command GetRamCapacity:

PluginRun("PlugIn","GetRamCapacity")

...script command PluginGet will retrieve integer output (capacity of RAM in bytes) into var integer variable:

PluginGet("PlugIn","var")

Once retrieved, you can do whatever you want with it. This example will show computer's RAM memory capacity in message box:

Message("RAM capacity of this computer (bytes):","var")

Code put together:

PluginRun("PlugIn","GetRamCapacity")

PluginGet("PlugIn","var")

Message("RAM capacity of this computer (bytes):","var")

Here's the result displayed in MMB's message box:

This was raw example of integer output, automatically displayed (used) in MMB.

You'll take advantage of numerical variable type, to perform math operations on the result retrieved from PlugIn.

Example above, if enhanced with MMB's script math functions, can look like this:

PluginRun("PlugIn","GetRamCapacity")

PluginGet("PlugIn","var")

Message("RAM capacity of this computer (bytes):","var")

var =INT (var/1024)

Message("RAM capacity of this computer (kbytes):","var")

var =INT (var/1024)

Message("RAM capacity of this computer (mbytes):","var")

Results displayed in MMB:





PlugIn's event integer output example

Just like in advanced string output case, PlugIns might send you integer output as event.

When will you see that happening ? If something is in progress (like media file playback, local or network file transfer) and PlugIn can send you current progress value - it will be sent as event to output integer variable. You'll probably use it for progress bars / gauges in MMB, resized upon PlugIn's progress event.

Still didn't read about event handling ? Go to sections below Manual's examples and read about it !

Here comes example for virtual PlugIn's event integer output, in this case for file transfer progress.

Once event happens, script object set to catch key combination, sent by PlugIn, will use PluginGet to retrieve output variable.

This paragraph is dedicated to integer output variables, so in this case integer output will be retrieved:

PluginGet("PlugIn","var")

What will var be filled with ? Virtual PlugIn returns file transfer progress event, so if percentage of transfer is 50%, value will be:

50

You didn't expect it would be something else, heh. Once this event message is sent to var output integer variable, you'll either display it using some text object, resize some MMB's object (for e.g. Rectangle as gauge) or use if-statements to decide what to (if percentage is 100, for e.g.)

This code will pick integer output (progress percentage) and resize MMB's object labeled Rectangle:

PluginGet("PlugIn","var")

MoveObject("Rectangle","10,10,var,20")

To do something after file transfer through PlugIn is over, you'll use code similar to this example:

PluginGet("PlugIn","var")

If (var =100) Then

NextPage()

Return()

End

Some MMB PlugIn may contain movable control inside. So if PlugIn returns integer output as event upon control position change, code might look like this:

PluginGet("PlugIn","var")

Message("You changed equalizer to:","var")

Event handling

Events = happenings, developments that occur in MMB PlugIn and your application is being informed about 'em through:

Event handlers = MMB Script Objects that serve as a kind of the "net", catching events sent by PlugIns.

How this all works ?

As you see from examples in this manual, by using PlugIn commands you can receive output. But, in some cases, PlugIn can't return output right after PluginRun.

There are tasks with:

  • extensive data processing (coding/decoding, encryption/decryption, copying, loading, etc.),
  • prolonged waiting (network connections, system events, user interactions, etc.) and
  • periodic events (playback position changes, system time changes, etc.)

So how will MMB PlugIn react when some delayed event (result) in PlugIn occurs ? It will simulate key presses (individual or combinations of more keys) and send it to your MMB application !




To make things more adjustable, MMB PlugIns allow setting of key combinations that will be used. More about it later.

This scheme shows you sequence (procedure, path) of event being sent from PlugIn (1), through emulating key combination (2) and MMB Application (3) to Script object set to receive pressed key combination (in this case: CTRL+SHIFT+ALT+D):



That's it ! Key combination sent from PlugIn triggers MMB's Script object, set to catch exactly that keystrokes:

Now you know what are Event Handlers - script objects set to receive specific key combination (as image above shows). They are being triggered when event occurs, so all script lines inside will be executed. Of course, you can do whatever you want in these script lines, but it's usual to pick some output value (PlugIns will always give some output after event occurs) using:

PluginGet("PlugIn","var") - for integer outputs

PluginGet("PlugIn","var$") - for string outputs

These are usually first lines in event handler script objects.

Why ? Output values might change if you interact with PlugIn using some other commands before picking up event (string or integer) output, so it's preferrable to do it as soon as event occurs.

Scheme above uses key combination CTRL+SHIFT+ALT+D .

PlugIns allow you to set your own combinations, using PlugIn command with advanced string input. Remember that section explaining various PlugIn commands with strange variable inputs and outputs ? That's right, we'll use advanced string input type with PlugIn command to set key combination for event handling !

Of course, you'll have to refer to PlugIn's documentation and see exact name of command being used for this task. So for purposes of this example, we'll (again) use virtual PlugIn with even more virtual command SetHandler:

First of all, use string input variable var$ to specify keys that should be used for event triggering. Being advanced string, it'll use comma ,to separate key names. First three keys are system keys (CTRL - Control key, SHIFT - Shift Key, ALT - Alt key), fourth can be any alphanumeric key.

Caps should be used for all key names, especially for fourth (alphanumeric) key - after all - MMB's Script objects set & catch only upper-case characters.

So. First script line will assign key names:

var$ ='CTRL,SHIFT,ALT,U'

Maybe you don't wanna use all system keys ? Just leave commas in place where system key won't be used:

var$ ='CTRL,,ALT,U'

String above leaves out SHIFT key.

var$ =',SHIFT,ALT,U'

And this string above leaves out CTRL key.

var$ =',,,U'

With this string, PlugIn ain't using system keys at all ! Just U character. But using only alphanumeric keys should be avoided if your application accepts any inputs from it's users - otherwise, U might be very popular character in your app ;-)

Notice 1: alphanumeric (fourth) key is obligatory.

Notice 2: specified key combinations should not be occupied by various task schedulers, automation tools and similar - these tools can register key combinations globally in operating system, so author of this manual recommends using strange combinations like:

var$='CTRL,SHIFT,ALT, ]' or var$ ='CTRL,SHIFT,ALT, 0 '

Enough about combinations ! Let's nicely assign value of var$ variable to PlugIn using PluginSet :

PluginSet("PlugIn","var$")

Now when PlugIn input variable is set, the only thing left to do is call PluginRun and execute command which PlugIn uses for setting of event handler key combination (virtual PlugIn uses SetHandler command).

PluginRun("PlugIn","SetHandler")

Lines are scattered around, let's put 'em together !

var$='CTRL,SHIFT,ALT, ]'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","SetHandler")

With these three lines, you set PlugIn handler key combination.

You're not done, you know ? Don't forget, something else must be set to this key combination !

- Fido ?

Nope.

- Coffee ?

Nope.

- Neighbour ?

That would be interesting, but in this case - nope.

- Maybe MMB's Script object, a.k.a. Event Handler ?

YEP !

On image above it's visible that Script object in it's first line retrieves PlugIn string output:

PluginGet("PlugIn","item$")

Depending on PlugIn and events, triggered event will fill either output integer or output string variable. You should read PlugIn's documentation and check what variable is being returned.

Generally, PlugIns use output string variables to return important events like:

CONNECTED

POSITION CHANGED

FILE COPIED

Files Dropped

(because of MMB scripting language, being case-sensitive, make sure to write events using correct case letters when you use if-statements in script lines)

PlugIns use output integer variables mostly to return media file position, either by percentage or original format:

12

99

7321

Once again, in practice, under event handler (Script object),

you'll use:

PluginGet("PlugIn","event$")

...to retrieve string variable output of triggered event, and

PluginGet("PlugIn","event")

...to retrieve integer variable output of triggered event.

Once variables are filled with PlugIn event output, you can display events using some text object:

LoadText("Text","event$")

 

LoadText("SoundPosition","event")

...or use if-statements to decide what your application should do when some event occurs. This example uses virtual event generated by virtual PlugIn that informs your application about connection to Internet:

PluginGet("PlugIn","event$")

If (event$ ='Connected to Internet') then

Message("PlugIn detected Internet connection","")

Return()

End

Once again ! This script is put into Script object, a.k.a. event handler, set to receive key combination from PlugIn.


Important notice on Event Handling subject:

Receiving of events by event handlers in MMB ain't always available - while PlugIns send key strokes, if your MMB application is not focused - these key strokes might be sent to

-> some other application ! <-

Also, using of dialogboxes in application could become difficult if events are sent repeatedly, because PlugIns try to focus window of main application.

To avoid dialogbox defocusing, temporarily turn off sending of events in PlugIn (if available as PlugIn feature) while dialogbox is being used, and turn back on when you're done using 'em.

Frequent, repetitionous event sending might also cause interference with end-user's pressing of system keys (if being used).

Future releases of MMB shall feature advanced approach to this subject, so hopefully events will be easier for both PlugIn developers and PlugIn users.

Color properties

MMB Visual PlugIns have another very neat feature - colors of their objects can be changed dynamically, on run-time. This is very important, giving application end-users ability to adjust visual properties according to their preferences.

There are usually two color properties you can set :

  • background (back) color - sets background color of PlugIn's window or object
  • foreground (font) color - sets foreground (or font) color of PlugIn's window or object

Changing of color properties is using PlugIn command with advanced string input. Once again, like in event handling case, we'll use advanced string input type with PlugIn command, this time to set color properties.

To specify color as input parameter, MMB PlugIns use RGB color system, just like monitors, TVs - and software, of course.

RGB stands for:

Red

Green

Blue

...or...




These three components represent basic colors. When you combine them in different ratios, all other colors can be displayed.


Setting of ratios, naturally, requires range of available values.

MMB PlugIns use the same range already known from standard windows color boxes:

        0 - 255

Lower value of color component means lower participation of that color in RGB result:

  • 0 - lowest value, removes component participation
  • 255 - highest value, component will participate 100%

Advanced string for setting of PlugIn color property uses comma , as separator between three basic color components:

red, green,blue

And with values looks like this:

255, 150,50

...in practice:

var$=' 255,150, 50'

Combination of this color component values will result in this color:





That means - either PlugIn's foreground or background will become orange after running color property command.

As usual, you'll refer to PlugIn's documentation for exact command names. For purposes of this manual, let's use virtual PlugIn's background color command SetBackColor .

First of all, var$ is used as input string variable for setting of advanced string - color values of basic three components:

var$ ='170,40,170'

With PluginSet, color values in var$ are assigned to PlugIn:

PluginSet("PlugIn","var$")

Once values are set, call PluginRun to execute virtual PlugIn's command SetBackColor for setting of background color:

PluginRun("PlugIn","SetBackColor")

The result is pinky-like PlugIn background color:




Similar script lines would be used for setting of font color. Let's use virtual PlugIn's font color command SetFontColor:

var$ ='102,102,153'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","SetFontColor")

The result is blue-gray PlugIn font color:

PlugIn's Text

Ability to change colors on run-time enables simulating color changing animation, through loops:

For i=1 To 255

var$ =CHAR(i)+',102,153'

PluginSet("PlugIn","var$")

PluginRun("PlugIn","SetFontColor")

Pause("20")

Next i

For skinnable applications, you'll probably use PlugIn color features to adjust appearance, according to loaded skin.

Color values should be saved, for example using MMB's Registry script commands:

SaveVariable ("BackColor","var$")

...and loaded / applied on application startup:

LoadVariable ("BackColor","var$")

PluginSet("PlugIn","var$")

PluginRun("PlugIn","SetFontColor")

MMB PlugIns: Summary

By reading manual, you found out this about MMB PlugIns:

  • they're not like any other software plug-ins
  • ain't looking like space shuttle or AC/DC plug, but 2D window in MMB application - sometimes visible, sometimes not
  • almost all are Type 1 PlugIns so you'll need more copies of DLL files to run more than one instance
  • all settings & processing is coordinated through MMB's script language, using string and integer variables
  • PlugIn Constitution recognizes three laws (commands): PluginSet, PluginRun & PluginGet
  • there are numerous variations on variable input & output subject - some PlugIn commands take inputs, some give outputs, strange ones neither give or take...
  • always refer to original PlugIn's documentation for command labels, input & output parameters
  • strange thing - event handling - informs your application when something (delayed) happens in PlugIn
  • MMB PlugIns are downloadable from MMB-related resource sites or PlugIn author's sites
  • Mad dog Fido still runs around the planet, collecting bones

The end is near, prepare !

...to get on to some serious business, of course ! ;-)

Like any Operator's Manual - this one would be nothing else but just a bunch of pages with pictures & schemes if it's contents ain't transfered into practice !

Move to (more-less, hah) real MMB world now - get those nasty PlugIns you spent download hours on - and open wide these new windows, get fresh air into your project !

Learn. Earn. Enjoy.

Here are a few more words from author of this Manual...

I find this to be a collection of answers to many times asked plugin-related questions. MMB PlugIn developers will greately appreciate if users spend enough time to get familiar with PlugIns through this manual, thus leaving more available time to PlugIn developers.

And who are these MMB PlugIn developers ?

- a bunch of ordinary guys doing PlugIns for a hobby, more on voluntary basis than with commercial attentions

Are they a part of Mediachance team ?

- no, PlugIn developers are not connected to Mediachance dev team

What about PlugIn support ?

- if PlugIn developer doesn't provide his own support system, you can post questions, suggestions & bug reports on MMB Forums. Please be aware of this: PlugIn developers are one-man-bands, having ordinary jobs & lives - so 24/7 support can hardly be expected, especially for older freeware PlugIns. Of course, commercial products mostly have good support - and for questions on freeware PlugIn subjects you'll find good souls on MMB Forums, ready to help (except in bug report cases) :-)

Are .mbd demos coming with PlugIns ?

- yes, MMB PlugIns usually come with demos, showing how commands mentioned in documentation work in practice. Notice that PlugIn object paths in some demos will point to <SrcDir>\ - it's being used to lower PlugIn package redundancy (not providing DLL's more than once). In this case you'll adjust path to match a folder where PlugIn's DLL resides.

Another case is when DLL comes <Embedded>\ : if you cannot find DLL in the package, just go to Window's Temporary Folder after running PlugIn's demo - there you'll find DLL file and it can be copied wherever you want.

What about legal issues of using PlugIns in commercial products ?

- if specific legal or any other limitation is not mentioned in PlugIn's documentation / readme file, it can be used in any project, commercial or not. The real beauty behind MMB PlugIns is - purchasing of PlugIns is very small investment, compared to their features, power and the fact they'll even sometimes cover hardest parts of your applications, saving you time & giving a good night sleep, using royalty-free concept.

Back to Manual's opening story - your neighbour's now got something to think about ! While he's struggling with variables - you're on event handling ! As he gets to events - your project is already out there, impressing customers around the planet ! Just make sure he doesn't get a copy of manual himself, hah...


Don't forget - this doesn't have to be the last & only one version of MMB PlugIns: Operator's Manual. If MMB users show support towards this tutorial, it will be refreshed with many new examples, updated according to changes in MMB.

And Fido might get into a better mood too, catching those bones !

MMB PlugIns: Operator's Manual

Author of manual hopes you enjoyed reading all these pages, and with some luck learned something (or at least laughed while reading).

Being one of MMB PlugIn authors, I noticed more than once how lack of good reference can delay user's projects, result in lame solutions and eat great amount of time to both MMB users and PlugIn developers (who write explanations and demos over and over again). MMB PlugIns: Operator's Manual should cover both general and specific aspects of MMB PlugIn usage, helping MMB users understand that savage beast hidden in the dark.

While most of MMB users do not know how to get along with PlugIns, making of this Manual was pretty much a natural thing to do.

Author's contact info

e-mail: bokzy@ hi.hinet.hr

web: http://www.bokzy.com

ICQ: 12610160

This manual is free for personal use. If you find it helpful while building commercial products, please support development & maintenance of this manual and donate money either by purchasing author's plugins or by using payment arranged with author of this manual.

MMB PlugIns: Operator's Manual (V1, 01.06.2003.)

by Bojan Oljaca (a.k.a. Bokzy)

All rights reserved.

No part of this manual shall be reproduced or copied by any means (electronic, mechanical, photocopying, recording or otherwise) for commercial purposes without permission from the author. It may be used for personal educational purposes only.

No patent liability is assumed with respect to the use of the information contained herein. Although precaution has been taken in the preparation of this manual, the author assumes no responsibility for errors or omissions. Nor is any liability assumed for damages resulting from the use of the information contained herein.

All terms mentioned in this manual that are known to be trademarks or service marks have been appropriately capitalized. Author cannot attest to the accuracy of this information. Use of a term in this manual should not be regarded as affecting the validity of any trademark or service mark.

Every effort has been made to make this manual as complete and as accurate as possible, but no warranty or fitness is implied. The information provided is on an "as is" basis. The author shall have neither liability nor responsibility to any person or entity with respect to any loss or damages arising from the information contained in this manual.

 

This is edited version of MMB PlugIns: Operator's Manual. Original manual can be downloaded from http://www.bokzy.com